package com.jzo2o.orders.manager.handle;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.jzo2o.api.trade.RefundRecordApi;
import com.jzo2o.api.trade.dto.response.ExecutionResultResDTO;
import com.jzo2o.common.constants.UserType;
import com.jzo2o.orders.base.enums.OrderPayStatusEnum;
import com.jzo2o.orders.base.enums.OrderRefundStatusEnum;
import com.jzo2o.orders.base.enums.OrderStatusEnum;
import com.jzo2o.orders.base.model.domain.Orders;
import com.jzo2o.orders.base.model.domain.OrdersRefund;
import com.jzo2o.orders.manager.model.dto.OrderCancelDTO;
import com.jzo2o.orders.manager.service.IOrdersManagerService;
import com.jzo2o.orders.manager.service.IOrdersRefundService;
import com.jzo2o.orders.manager.strategy.OrderCancelStrategyManager;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;

@Component
@Slf4j
/**
 * 退款处理类
 */
public class OrdersHandler {

    @Autowired
    private IOrdersRefundService ordersRefundService;
    @Autowired
    private RefundRecordApi refundRecordApi;
    @Autowired
    private IOrdersManagerService ordersManagerService;
    @Autowired
    private OrderCancelStrategyManager orderCancelStrategyManager;
    /**
     * 定时读取退款表中的数据, 然后调用支付服务的退款接口
     */
    @XxlJob(value = "handleRefundOrders")
    public void handleRefundOrders(){
        List<OrdersRefund> ordersRefundList = ordersRefundService.queryRefundOrderListByCount(100);
        //判断集合是否有值
        if (CollectionUtil.isEmpty(ordersRefundList)) {
            return;
        }
        for (OrdersRefund ordersRefund : ordersRefundList) {
            log.info("开始处理退款订单:{}", ordersRefund);
            //调用退款接口
            ExecutionResultResDTO res =
                    refundRecordApi.refundTrading(ordersRefund.getTradingOrderNo(), ordersRefund.getRealPayAmount());
            //根据接口的返回值做处理
            if (ObjectUtil.isNotEmpty(res)) {
                if (ObjectUtil.equal(res.getRefundStatus(), OrderRefundStatusEnum.REFUNDING.getStatus())){
                    //退款中 不处理 等待微信完成退款
                    continue;
                }
                //退款后续操作
                afterRefund(ordersRefund,res);
            }
        }
    }

    private void afterRefund(OrdersRefund ordersRefund, ExecutionResultResDTO res) {
        //处理订单表中 退款状态 refund_status 、支付服务退款单号refund_no 、第三方支付的退款单号 refund_id
        Orders orders = new Orders();
        //设置退款状态
        orders.setRefundStatus(res.getRefundStatus());
        //设置支付服务退款单号
        orders.setRefundNo(res.getRefundNo());
        //设置第三方支付的退款单号
        orders.setRefundId(res.getRefundId());
        orders.setId(ordersRefund.getId());

        boolean b = ordersManagerService.updateById(orders);

        //删除退款表中的数据
        if (b){
            ordersRefundService.removeById(ordersRefund.getId());
        }
    }

    /**
     * 取消超时订单
     */
    @XxlJob("cancelOverTimePayOrder")
    public void cancelOverTimePayOrder() {
        //1. 查询超时未支付的订单
        //select * from orders where orders_status = 0 and pay_status = 2 and create_time < 当前时间 - 15分钟
        List<Orders> list = ordersManagerService.lambdaQuery()
                .eq(Orders::getOrdersStatus, OrderStatusEnum.NO_PAY.getStatus())//orders_status = 0
                .eq(Orders::getPayStatus, OrderPayStatusEnum.NO_PAY.getStatus())//pay_status = 2
                .lt(Orders::getCreateTime, LocalDateTime.now().minusMinutes(15))//create_time < 当前时间 - 15分钟
                .last("limit 100")//限制每次最多查100条
                .list();
        if (CollUtil.isEmpty(list)){
            return;
        }

        //2. 遍历集合, 获取到每一笔订单
        for (Orders orders : list) {
            //然后去取消
            OrderCancelDTO orderCancelDTO = new OrderCancelDTO();
            orderCancelDTO.setId(orders.getId());//订单id
            orderCancelDTO.setCurrentUserId(0L);//当前用户id
            orderCancelDTO.setCurrentUserName("系统定时任务");//当前用户名称
            orderCancelDTO.setCurrentUserType(UserType.SYSTEM);//当前用户类型
            orderCancelDTO.setCancelReason("超时未支付");//取消原因
            orderCancelStrategyManager.cancel(orderCancelDTO);
        }
    }
}
